package com.jweb.framework.http.interceptors;

import com.jweb.framework.core.ContextEx;
import com.jweb.framework.core.CoreException;
import com.jweb.framework.core.CoreRuntimeException;
import com.jweb.framework.core.CoreSuperException;
import com.jweb.framework.core.RuntimeSuperException;
import com.jweb.framework.core.channel.ChannelContext;
import com.jweb.framework.core.channel.ChannelInterceptor;
import com.jweb.framework.core.channel.Transform;
import com.jweb.framework.core.channel.interceptors.ExceptionHandler;

/**
 * 修改人： Thomas
 * 修改内容：新增 
 * 类说明：渠道解析拦截器
 */
public class TransformInterceptor<Request , Response> implements ChannelInterceptor<Request, Response> {
	
	private Transform[] decodeTransforms ;
	private Transform[] encodeTransforms ;
	private ExceptionHandler exceptionHandler ;
	
	public void setDecodeTransforms(Transform[] deTs){
		this.decodeTransforms = deTs ;
	}
	
	public void setEncodeTransforms(Transform[] enTs){
		this.encodeTransforms = enTs ;
	}
	
	public void setExceptionHandler(ExceptionHandler exceptionHandler){
		this.exceptionHandler = exceptionHandler ;
	}
	
	public void onRequest(ChannelContext channelContext , ContextEx contextEx) throws CoreException {
		if(channelContext.getRequestPayload() == null){
			throw new CoreRuntimeException("JAVACO0009", "no_request_payload");
		}
		Object obj = transform(channelContext.getRequestPayload() , this.decodeTransforms , contextEx.getProcessId()) ;
		
		channelContext.setRequestPayload(obj);
	}
	
	private Object transform(Object requestPayload , Transform[] transforms , String processId) throws CoreException {
		
		Object obj = requestPayload ;
		if(transforms != null){
			for(Transform t : transforms){
				if(t.support(obj)){
					obj = t.transform(obj , processId) ;
				}
			}
		}
		
		return obj ;
	}
	
	public void onResponse(ChannelContext channelContext , ContextEx contextEx , Throwable throwable) {
		
		if((throwable != null) && (this.exceptionHandler != null)){
			this.exceptionHandler.handleException(throwable , contextEx);
			channelContext.setResponsePayload(contextEx.getDataMap());
		}
		
		if(channelContext.getResponsePalyload() == null){
			return ;
		}
		
		try {
			Object obj = transform(channelContext.getResponsePalyload() , this.encodeTransforms , contextEx.getProcessId()) ;
			channelContext.setResponsePayload(obj);
		} catch (CoreSuperException e) {
			throw new RuntimeSuperException(e.getCode() , e.getArguments() , e.getDefaultMessage() , e);
		}
		
	}
}
